package com.sound.ampache;

/* Copyright (c) 2010 Brian Kirkman <kirkman.brian@gmail.com>
*
* +------------------------------------------------------------------------+
* | This program is free software; you can redistribute it and/or          |
* | modify it under the terms of the GNU General Public License            |
* | as published by the Free Software Foundation; either version 3         |
* | of the License, or (at your option) any later version.                 |
* |                                                                        |
* | This program is distributed in the hope that it will be useful,        |
* | but WITHOUT ANY WARRANTY; without even the implied warranty of         |
* | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          |
* | GNU General Public License for more details.                           |
* |                                                                        |
* | You should have received a copy of the GNU General Public License      |
* | along with this program; if not, write to the Free Software            |
* | Foundation, Inc., 59 Temple Place - Suite 330,                         |
* | Boston, MA  02111-1307, USA.                                           |
* +------------------------------------------------------------------------+
*
* Special thanks to the following: 
* Kevin Purdy, author of Amdroid, for much of the code used in this project
* 
* Jorge Ramon, author of MiamiCoder blog, for many great BlackBerry examples
* published on his blog.
* 
* 
*/

import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Random;
import java.util.Vector;

import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;

import com.sound.ampache.objects.Album;
import com.sound.ampache.objects.Artist;
import com.sound.ampache.objects.Playlist;
import com.sound.ampache.objects.Song;
import com.sound.ampache.objects.Tag;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.container.MainScreen;



class SongPlaylist extends MainScreen implements HTTPTransportListener {
	
	public Vector songPlaylist = new Vector();
	public Vector playingSongs = new Vector();
	public Vector playedSongs = new Vector();
	
	private Integer playingSong = null;
	
	private boolean random = false;
	private boolean repeatAll = false;
	private boolean repeatOne = false;
	private boolean endOfPlaylist = false;
	private boolean startOfPlaylist = false;
	
	private Dialog statusDlg;
	
	SongPlaylist()
	{
		Bitmap icon = Bitmap.getBitmapResource("img/download.png"); 
		statusDlg = new Dialog("Downloading...",null,null,0,icon); 
	}
	
	
	public void addAlbumToPlaylist(Album album) {
		statusDlg.show();
		try {
	        ampacheberry.comm.setHTTPTransportListener(this);
	        ampacheberry.comm.send("album_songs", album.id); 
	
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}
	
	
	public void addPlaylistToPlaylist(Playlist playlist) {
		statusDlg.show();
		try {
	        ampacheberry.comm.setHTTPTransportListener(this);
	        ampacheberry.comm.send("playlist_songs", playlist.id); 
	
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}
	
	
	public void addArtistToPlaylist(Artist artist) {
		statusDlg.show();
		try {
	        ampacheberry.comm.setHTTPTransportListener(this);
	        ampacheberry.comm.send("artist_songs", artist.id); 
	
		} catch (Exception e1) {
			e1.printStackTrace();
		}		
	}
	
	
	public void addTagToPlaylist(Tag tag) {
		statusDlg.show();
		try {
	        ampacheberry.comm.setHTTPTransportListener(this);
	        ampacheberry.comm.send("tag_songs", tag.id); 
	
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}
	
	
	public void addSongToPlaylist(Song song) {
		Vector thisSong = new Vector();
    	thisSong.addElement(song);
    	processResponse(thisSong);
    }


	
	public void writePlaylist() {
    	String playlistContents = "#EXTM3U\n";
    	
    	for (Enumeration e = songPlaylist.elements(); e.hasMoreElements();)
    	{
    		Song thisSong = new Song();
    		thisSong = (Song) e.nextElement();
    		playlistContents += "#EXTINF:" + 
    			thisSong.time + "," + 
    			thisSong.artist + " - " +
    			thisSong.name + "\n" +
    			thisSong.url + "\n";
    	}
    	
    	//String fullPath = "file:///SDCard/ampache_playlist.txt";
    	String fullPath = "file:///store/home/user/music/ampache_playlist.m3u";

    	try {
    	    FileConnection fconn = (FileConnection) Connector.open(fullPath, Connector.READ_WRITE);

    	    if (fconn.exists()) {
    	        fconn.delete();
    	    }

    	    fconn.create();
    	    OutputStream os = fconn.openOutputStream();
    	    os.write(playlistContents.getBytes());
    	    os.close();
    	    fconn.close();
    	}
    	catch (IOException e) {
    	    System.out.println("Oh no!!!! " + e.toString());
    	}
	}

	
	public void processResponse(final Vector data) {
        UiApplication.getUiApplication().invokeLater(new Runnable() {
            public void run()
            {
    	    	for (Enumeration e = data.elements(); e.hasMoreElements();)
    	    	{
    	    		Song thisSong = new Song();
    	    		thisSong = (Song) e.nextElement();
    	    		songPlaylist.addElement(thisSong);
    	    		
    	    		//Create playing songs array - just an integer stack.
    	    		playingSongs.addElement(new Integer(songPlaylist.size() - 1));
    	    	}
    	    	
    	    	writePlaylist();
    	    	ampacheberry.playlistScreen.getList();
    	    	ampacheberry.redrawHomescreen();
    	    	statusDlg.close();
            }
        });	
	}
	
	
	public boolean clearPlaylist() {
		if (!ampacheberry.playerScreen.getSongIsPlaying()) {
			songPlaylist.removeAllElements();
			playedSongs.removeAllElements();
			playingSongs.removeAllElements();
			playingSong = null;
			ampacheberry.playerScreen.setSongInfo();
			ampacheberry.playerScreen.setSongArt();
			return true;
		} else {
			Dialog.alert("Cannot Clear Playlist While Song Is Playing!");
			return false;
		}
	}
	
	
	public boolean delSong(int songNum) {
		if (playingSong.intValue() != songNum) {
			songPlaylist.removeElementAt(songNum);
			playedSongs.removeElement(new Integer(songNum));
			playingSongs.removeElement(new Integer(songNum));
			
			//Decrement playing song
			if (playingSong.intValue() > songNum) {
				playingSong = new Integer (playingSong.intValue() - 1);
			}
			
			//Decrement playedSongs vector elements
	    	for (int i = 0; i < playedSongs.size(); i++) {
	    		if (((Integer) playedSongs.elementAt(i)).intValue() > songNum) {
	    			playedSongs.setElementAt(
	    					new Integer (((Integer) playedSongs.elementAt(i)).intValue() - 1), i);
	    		} 
	    	}
	    	
	    	//Decrement playingSongs vector elements
	    	for (int i = 0; i < playingSongs.size(); i++) {
	    		if (((Integer) playingSongs.elementAt(i)).intValue() > songNum) {
	    			playingSongs.setElementAt(
	    					new Integer (((Integer) playingSongs.elementAt(i)).intValue() - 1), i);
	    		} 
	    	}
	    	return true;
		} else {
			Dialog.alert("Cannot Delete Currently Playing Song!");
			return false;
		}
	}
	
		
	public void advanceSong() {	
		//Currently playing song should always be in the playedIndex.
		//Most of the time, it will be the last element, unless an already played
		//song was manually replayed from the playlist.
		int playedIndex = playedSongs.indexOf(playingSong);
		endOfPlaylist = false;
			
		if (playedIndex < playedSongs.size() - 1 && playedIndex != -1) { //not the last element
			playingSong = (Integer) playedSongs.elementAt(playedIndex + 1);
		} else { //last element or no elements
			if (playingSongs.size() > 0) { //there are still songs to play
				if (random) {
					Random myGenerator = new Random(System.currentTimeMillis());
					int nextRandSongIndex = myGenerator.nextInt(playingSongs.size());
					playedSongs.addElement(playingSongs.elementAt(nextRandSongIndex));
					playingSongs.removeElementAt(nextRandSongIndex);
					playingSong = (Integer) playedSongs.lastElement();
				} else {
					playedSongs.addElement(playingSongs.elementAt(0));
					playingSongs.removeElementAt(0);
					playingSong = (Integer) playedSongs.lastElement();
				}
			} else if (playedSongs.size() > 0){ //no songs left to play and playedSongs exist
				if (repeatAll) { //loop back to beginning
					playingSong = (Integer) playedSongs.elementAt(0);
				} else {  
					endOfPlaylist = true;
				}
			}	
		}
	}
	
	
	public void backSong() {
		int playedIndex = playedSongs.indexOf(playingSong);
		startOfPlaylist = false;

		if (playedIndex > 0) {
			playingSong = (Integer) playedSongs.elementAt(playedIndex - 1);
		} else {
			startOfPlaylist = true;
		}
	}
	
	
	public Integer getPlayingSong() {
		//Advance song if no song has been queued into playedSong
		if (playedSongs.isEmpty() && playingSongs.size() > 0) {
			advanceSong();
		}
		return playingSong;
	}
	
	
	public void playSongNum(int num) {
		Integer songToPlay = new Integer(num);
		int playingIndex = playingSongs.indexOf(songToPlay);
		
		if (!random) {
			playedSongs.removeAllElements();
			playingSongs.removeAllElements();
			for (int i = 0; i < num + 1; i++) {
				playedSongs.addElement(new Integer(i));
			}
			for (int i = num + 1; i < songPlaylist.size(); i++) {
				playingSongs.addElement(new Integer(i));
			}
		} else { //random
			if(playingIndex > -1) {
				playingSongs.removeElement(songToPlay);
				playedSongs.addElement(songToPlay);
			}
		}
		playingSong = songToPlay;
	}
	
	
	public void setRandom(boolean setRnd) {
		if(setRnd) {
			//When setting random do the following:
			//Reset the played and playing vectors
			//Create the playing vector 0 - size()
			//Pull out the playing song and place in playedSongs
			
			random = true;
			
			playedSongs.removeAllElements();
			playingSongs.removeAllElements();
			
			for (int i = 0; i < songPlaylist.size(); i++) {
				playingSongs.addElement(new Integer(i));
			}

			if (playingSong != null) {
				playingSongs.removeElement(playingSong);
				playedSongs.addElement(playingSong);
			}
		} else {
			//When unsetting random do the following:
			//Reset the played and playing vectors
			//Create the played vector 0 - playingSong
			//Create the playing vector playingSong + 1 - size() - 1
			
			random = false;
			playedSongs.removeAllElements();
			playingSongs.removeAllElements();
			
			if (playingSong != null) {
			int songNum = playingSong.intValue();
				for (int i = 0; i < songNum + 1; i++) {
					playedSongs.addElement(new Integer(i));
				}
				
				for (int i = songNum + 1; i < songPlaylist.size(); i++) {
					playingSongs.addElement(new Integer(i));
				}
			}
		}
	}

	
	public boolean getRandom() {
		return random;
	}
	
	public boolean getRepeatAll() {
		return repeatAll;
	}
	
	public void setRepeatAll(boolean setRptAll) {
		repeatAll = setRptAll;
	}
	
	public boolean getRepeatOne() {
		return repeatOne;
	}
	
	public void setRepeatOne(boolean setRptOne) {
		repeatOne = setRptOne;
	}
	
	public boolean getEndOfPlaylist() {
		return endOfPlaylist;
	}
	
	public boolean getStartOfPlaylist() {
		return startOfPlaylist;
	}
} 
